package com.rocksdata.mc.ui.activity;

import java.util.ArrayList;
import java.util.List;

import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event;
import org.xutils.view.annotation.ViewInject;

import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.ctz.commonframe.ui.BaseActivity;
import com.ctz.commonframe.ui.view.LockPatternView;
import com.ctz.commonframe.utils.LockPatternUtils;
import com.rocksdata.mc.R;
import com.rocksdata.mc.business.UserInfoManager;

@ContentView(R.layout.activity_gesturepassword_create)
public class GesturePasswordCreateActivity extends BaseActivity{
	private static final int ID_EMPTY_MESSAGE = -1;
	private static final String KEY_UI_STAGE = "uiStage";
	private static final String KEY_PATTERN_CHOICE = "chosenPattern";
    @ViewInject(R.id.gesturepwd_create_lockview)
	private LockPatternView mLockPatternView;
    @ViewInject(R.id.right_btn)
	private Button mFooterRightButton;
    @ViewInject(R.id.reset_btn)
	private Button mFooterLeftButton;
    @ViewInject(R.id.gesturepwd_create_text)
	protected TextView mHeaderText;

	protected List<LockPatternView.Cell> mChosenPattern = null;
	private Toast mToast;
	private Stage mUiStage = Stage.Introduction;
	private View mPreviewViews[][] = new View[3][3];
	private int index = 0;
	private boolean flag = false;
	private String main_passwd = "";
	/**
	 * The patten used during the help screen to show how to draw a pattern.
	 */
	private final List<LockPatternView.Cell> mAnimatePattern = new ArrayList<LockPatternView.Cell>();

	/**
	 * The states of the left footer button.
	 */
	enum LeftButtonMode {
		Cancel(android.R.string.cancel, true), CancelDisabled(android.R.string.cancel, false), Retry(
				R.string.lockpattern_retry_button_text,
				true), RetryDisabled(R.string.lockpattern_retry_button_text, false), Gone(ID_EMPTY_MESSAGE, false);

		/**
		 * @param text
		 *            The displayed text for this mode.
		 * @param enabled
		 *            Whether the button should be enabled.
		 */
		LeftButtonMode(int text, boolean enabled) {
			this.text = text;
			this.enabled = enabled;
		}

		final int text;
		final boolean enabled;
	}

	/**
	 * The states of the right button.
	 */
	enum RightButtonMode {
		Continue(R.string.lockpattern_continue_button_text, true), ContinueDisabled(
				R.string.lockpattern_continue_button_text,
				false), Confirm(R.string.lockpattern_confirm_button_text, true), ConfirmDisabled(
						R.string.lockpattern_confirm_button_text, false), Ok(android.R.string.ok, true);

		/**
		 * @param text
		 *            The displayed text for this mode.
		 * @param enabled
		 *            Whether the button should be enabled.
		 */
		RightButtonMode(int text, boolean enabled) {
			this.text = text;
			this.enabled = enabled;
		}

		final int text;
		final boolean enabled;
	}

	/**
	 * Keep track internally of where the user is in choosing a pattern.
	 */
	protected enum Stage {

		Introduction(R.string.lockpattern_recording_intro_header, LeftButtonMode.Cancel,
				RightButtonMode.ContinueDisabled, ID_EMPTY_MESSAGE, true), HelpScreen(
						R.string.lockpattern_settings_help_how_to_record, LeftButtonMode.Gone, RightButtonMode.Ok,
						ID_EMPTY_MESSAGE, false), ChoiceTooShort(R.string.lockpattern_recording_incorrect_too_short,
								LeftButtonMode.Retry, RightButtonMode.ContinueDisabled, ID_EMPTY_MESSAGE,
								true), FirstChoiceValid(R.string.lockpattern_pattern_entered_header,
										LeftButtonMode.Retry, RightButtonMode.Continue, ID_EMPTY_MESSAGE,
										false), NeedToConfirm(R.string.lockpattern_need_to_confirm,
												LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
												ID_EMPTY_MESSAGE,
												true), ConfirmWrong(R.string.lockpattern_need_to_unlock_wrong,
														LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
														ID_EMPTY_MESSAGE, true), ChoiceConfirmed(
																R.string.lockpattern_pattern_confirmed_header,
																LeftButtonMode.Cancel, RightButtonMode.Confirm,
																ID_EMPTY_MESSAGE, false);

		/**
		 * @param headerMessage
		 *            The message displayed at the top.
		 * @param leftMode
		 *            The mode of the left button.
		 * @param rightMode
		 *            The mode of the right button.
		 * @param footerMessage
		 *            The footer message.
		 * @param patternEnabled
		 *            Whether the pattern widget is enabled.
		 */
		Stage(int headerMessage, LeftButtonMode leftMode, RightButtonMode rightMode, int footerMessage,
				boolean patternEnabled) {
			this.headerMessage = headerMessage;
			this.leftMode = leftMode;
			this.rightMode = rightMode;
			this.footerMessage = footerMessage;
			this.patternEnabled = patternEnabled;
		}

		final int headerMessage;
		final LeftButtonMode leftMode;
		final RightButtonMode rightMode;
		final int footerMessage;
		final boolean patternEnabled;
	}

	private void showToast(CharSequence message) {
		if (null == mToast) {
			mToast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
		} else {
			mToast.setText(message);
		}

		mToast.show();
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		mAnimatePattern.add(LockPatternView.Cell.of(0, 0));
		mAnimatePattern.add(LockPatternView.Cell.of(0, 1));
		mAnimatePattern.add(LockPatternView.Cell.of(0, 2));
		mAnimatePattern.add(LockPatternView.Cell.of(1, 1));
		mAnimatePattern.add(LockPatternView.Cell.of(2, 0));
		mAnimatePattern.add(LockPatternView.Cell.of(2, 1));
		mAnimatePattern.add(LockPatternView.Cell.of(2, 2));

		mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
		mLockPatternView.setTactileFeedbackEnabled(true);

		initPreviewViews();
		if (savedInstanceState == null) {
			updateStage(Stage.Introduction);
			updateStage(Stage.HelpScreen);
		} else {
			// restore from previous state
			final String patternString = savedInstanceState.getString(KEY_PATTERN_CHOICE);
			if (patternString != null) {
				mChosenPattern = LockPatternUtils.stringToPattern(patternString);
			}
			updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
		}

	}

	private void initPreviewViews() {
//		mPreviewViews = new View[3][3];
//		mPreviewViews[0][0] = findViewById(R.id.gesturepwd_setting_preview_0);
//		mPreviewViews[0][1] = findViewById(R.id.gesturepwd_setting_preview_1);
//		mPreviewViews[0][2] = findViewById(R.id.gesturepwd_setting_preview_2);
//		mPreviewViews[1][0] = findViewById(R.id.gesturepwd_setting_preview_3);
//		mPreviewViews[1][1] = findViewById(R.id.gesturepwd_setting_preview_4);
//		mPreviewViews[1][2] = findViewById(R.id.gesturepwd_setting_preview_5);
//		mPreviewViews[2][0] = findViewById(R.id.gesturepwd_setting_preview_6);
//		mPreviewViews[2][1] = findViewById(R.id.gesturepwd_setting_preview_7);
//		mPreviewViews[2][2] = findViewById(R.id.gesturepwd_setting_preview_8);
	}

	private void updatePreviewViews() {
//		if (mChosenPattern == null)
//			return;
//		for (LockPatternView.Cell cell : mChosenPattern) {
//			mPreviewViews[cell.getRow()][cell.getColumn()]
//					.setBackgroundResource(R.drawable.gesture_create_grid_selected);
//
//		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putInt(KEY_UI_STAGE, mUiStage.ordinal());
		if (mChosenPattern != null) {
			outState.putString(KEY_PATTERN_CHOICE, LockPatternUtils.patternToString(mChosenPattern));
		}
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
			if (mUiStage == Stage.HelpScreen) {
				updateStage(Stage.Introduction);
				return true;
			}
		}
		if (keyCode == KeyEvent.KEYCODE_MENU && mUiStage == Stage.Introduction) {
			updateStage(Stage.HelpScreen);
			return true;
		}
		return false;
	}

	private Runnable mClearPatternRunnable = new Runnable() {
		public void run() {
			mLockPatternView.clearPattern();
		}
	};

	protected LockPatternView.OnPatternListener mChooseNewLockPatternListener = new LockPatternView.OnPatternListener() {

		public void onPatternStart() {
			mLockPatternView.removeCallbacks(mClearPatternRunnable);
			patternInProgress();
		}

		public void onPatternCleared() {
			mLockPatternView.removeCallbacks(mClearPatternRunnable);
		}

		public void onPatternDetected(List<LockPatternView.Cell> pattern) {
			if (pattern == null)
				return;
			if (mUiStage == Stage.NeedToConfirm || mUiStage == Stage.ConfirmWrong) {
				if (mChosenPattern == null)
					throw new IllegalStateException("null chosen pattern in stage 'need to confirm");
				if (mChosenPattern.equals(pattern)) {
					updateStage(Stage.ChoiceConfirmed);
				} else {
					updateStage(Stage.ConfirmWrong);
				}
			} else if (mUiStage == Stage.Introduction || mUiStage == Stage.ChoiceTooShort) {
				if (pattern.size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
					updateStage(Stage.ChoiceTooShort);
				} else {
					mChosenPattern = new ArrayList<LockPatternView.Cell>(pattern);
					updateStage(Stage.FirstChoiceValid);
				}
			} else {
				throw new IllegalStateException("Unexpected stage " + mUiStage + " when " + "entering the pattern.");
			}
		}

		public void onPatternCellAdded(List<LockPatternView.Cell> pattern) {
			if (flag) {
				if (null != pattern) {
					int column = pattern.get(index).getColumn();
					int row = pattern.get(index).getRow();
					int num = numChange(column, row);
					main_passwd = main_passwd + num + "";
					index++;
				}
			}
		}

		private void patternInProgress() {
			mHeaderText.setText(R.string.lockpattern_recording_inprogress);
			mFooterLeftButton.setEnabled(false);
			mFooterRightButton.setEnabled(false);
		}
	};

	private void updateStage(Stage stage) {
		mUiStage = stage;
		if (stage == Stage.ChoiceTooShort) {
			mHeaderText.setText(getResources().getString(stage.headerMessage, LockPatternUtils.MIN_LOCK_PATTERN_SIZE));
		} else {
			mHeaderText.setText(stage.headerMessage);
		}

		if (stage.leftMode == LeftButtonMode.Gone) {
			mFooterLeftButton.setVisibility(View.GONE);
		} else {
			mFooterLeftButton.setVisibility(View.VISIBLE);
			mFooterLeftButton.setText(stage.leftMode.text);
			mFooterLeftButton.setEnabled(stage.leftMode.enabled);
		}

		mFooterRightButton.setText(stage.rightMode.text);
		mFooterRightButton.setEnabled(stage.rightMode.enabled);

		// same for whether the patten is enabled
		if (stage.patternEnabled) {
			mLockPatternView.enableInput();
		} else {
			mLockPatternView.disableInput();
		}

		mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);

		switch (mUiStage) {
		case Introduction:
			mLockPatternView.clearPattern();
			break;
		case HelpScreen:
			mLockPatternView.setPattern(LockPatternView.DisplayMode.Animate, mAnimatePattern);
			break;
		case ChoiceTooShort:
			mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
			postClearPatternRunnable();
			break;
		case FirstChoiceValid:
			break;
		case NeedToConfirm:
			mLockPatternView.clearPattern();
			updatePreviewViews();
			break;
		case ConfirmWrong:
			mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
			postClearPatternRunnable();
			break;
		case ChoiceConfirmed:
			break;
		}

	}

	// clear the wrong pattern unless they have started a new one
	// already
	private void postClearPatternRunnable() {
		mLockPatternView.removeCallbacks(mClearPatternRunnable);
		mLockPatternView.postDelayed(mClearPatternRunnable, 2000);
	}

    @Event(value = {R.id.right_btn, R.id.reset_btn}, type = View.OnClickListener.class)
    private void onClick(View v) {
		switch (v.getId()) {
            case R.id.reset_btn:
                if (mUiStage.leftMode == LeftButtonMode.Retry) {
                    mChosenPattern = null;
                    mLockPatternView.clearPattern();
                    updateStage(Stage.Introduction);
                } else if (mUiStage.leftMode == LeftButtonMode.Cancel) {
                    // They are canceling the entire wizard
                    finish();
                } else {
                    throw new IllegalStateException(
                            "left footer button pressed, but stage of " + mUiStage + " doesn't make sense");
                }

                break;
            case R.id.right_btn:
                if (mUiStage.rightMode == RightButtonMode.Continue) {
                    if (mUiStage != Stage.FirstChoiceValid) {
                        throw new IllegalStateException("expected ui stage " + Stage.FirstChoiceValid + " when button is "
                                + RightButtonMode.Continue);
                    }
                    updateStage(Stage.NeedToConfirm);
                    flag = true;
                } else if (mUiStage.rightMode == RightButtonMode.Confirm) {
                    if (mUiStage != Stage.ChoiceConfirmed) {
                        throw new IllegalStateException("expected ui stage " + Stage.ChoiceConfirmed + " when button is "
                                + RightButtonMode.Confirm);
                    }
                    saveChosenPatternAndFinish();
                } else if (mUiStage.rightMode == RightButtonMode.Ok) {
                    if (mUiStage != Stage.HelpScreen) {
                        throw new IllegalStateException(
                                "Help screen is only mode with ok button, but " + "stage is " + mUiStage);
                    }
                    mLockPatternView.clearPattern();
                    mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
                    updateStage(Stage.Introduction);
                }
                break;
        }
	}

	private void saveChosenPatternAndFinish() {
		UserInfoManager.saveGesturePassword(main_passwd);
        showToast("手势密码设置成功");
        finish();
	}

	private int numChange(int column, int row) {
		int num = 0;
//		if (row == 0) {
//			num = column + 1;
//		} else if (row == 1) {
//			num = column + 4;
//		} else if (row == 2) {
//			num = column + 7;
//		}
		num = row*3+column+1;
		return num;
	}
}
